﻿namespace Hotel.Module.Infrastructure
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using Hotel.Model.Infrastructure;

    public interface IStorageController : IDisposable
    {
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        IQueryable<T> GetQuery<T>() where T : IDistributedStorageEntity;

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        IEnumerable<T> Enumerate<T>() where T : IDistributedStorageEntity;
        
        /// <summary>
        /// Adds new entity to the storage
        /// </summary>
        /// <param name="tableEntity">Entity</param>
        /// <exception cref="ArgumentNullException">Fires if entity is null</exception>
        /// <exception cref="InvalidOperationException">Fires if Entity was not initialized</exception>
        void Add<T>(T tableEntity) where T : IDistributedStorageEntity;

        /// <summary>
        /// Updates some entity
        /// </summary>
        /// <param name="tableEntity">Entity</param>
        /// <exception cref="ArgumentNullException">Fires if entity is null</exception>
        /// <exception cref="InvalidOperationException">Fires if Entity was not initialized</exception>
        void Update<T>(T tableEntity) where T : IDistributedStorageEntity;

        /// <summary>
        /// Deletes entity
        /// </summary>
        /// <param name="tableEntity">Entity</param>
        /// <exception cref="ArgumentNullException">Fires if entity is null</exception>
        /// <exception cref="InvalidOperationException">Fires if Entity was not initialized</exception>
        void Delete<T>(T tableEntity) where T : IDistributedStorageEntity;

        //TODO comment
        /// <summary>
        /// 
        /// </summary>
        /// <param name="ID"></param>
        /// <returns></returns>
        T Find<T>(Predicate<T> match);

        

        void SaveChanges();
    }
}
